package com.weibo.click.local;

import java.awt.AWTException;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.datatransfer.StringSelection;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.util.Date;
import java.util.Iterator;
import java.util.Random;
import java.util.concurrent.atomic.AtomicInteger;

import javax.imageio.ImageIO;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.bj.barcode.ConstantStri;
import com.google.gson.Gson;
import com.sun.net.httpserver.Headers;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;
import com.weibo.click.ClipboardUtils;
import com.weibo.click.ControlUtils;
import com.weibo.click.QueryString;

public class AutoClickLocalServer {
	private int port;
	private java.util.Timer timer = null;
    private static String[] str=new String[378];
	private static  final AtomicInteger msgNum=new AtomicInteger(0);
	//startUpFFADSL.bat增加了自动挂断和连接ADSL的功能
    private String uploadedFile="";
	Log logger = LogFactory.getLog(AutoClickLocalServer.class);
	public AutoClickLocalServer() {
	}

	public AutoClickLocalServer(int port) {
		this.port = port;
	}

	public void start() {
		try {
		    InetSocketAddress address = new InetSocketAddress("127.0.0.1", port);
			HttpServer server = HttpServer.create(address, 0);
			ClipboardUtils clip = new ClipboardUtils();
			clip.clickFireFoxLogout();
			//执行ADSL脚本hangup脚本
			
			server.createContext("/", new HttpHandler() {
				public void handle(HttpExchange he) {
					try {
						String ip = he.getRemoteAddress().getAddress().getHostAddress();
						//logger.info("http消息发送的来源ip是："+ip);
						InputStream input_stream = he.getRequestBody();
						Headers paramHeaders = he.getRequestHeaders();
						Iterator params = paramHeaders.keySet().iterator();
						while (params.hasNext()) {
							String key = (String) params.next();
							String value = paramHeaders.getFirst(key);
							//logger.info("Key  = " + key + "--- Value = "+ value);
						}
						BufferedReader reader = new BufferedReader(
								new InputStreamReader(input_stream));
						StringBuilder str_builder = new StringBuilder();

						String line = null;
						while ((line = reader.readLine()) != null) {
							str_builder.append(line );
						}
						String qStr=str_builder.toString();
						logger.info("send parameters string is:  "+ qStr);
						QueryString qs = new QueryString(qStr);
						String [] resTick=new String[5];
						if(qStr.contains("action=")){
						   handleClickAction(qs);
						}else if(qStr.contains("method=ADSLlogout")){//必须把这个次序排前面
						   handleLogoutADSL(qs);
						}else if(qStr.contains("method=CleanHistory")){//必须把这个次序排前面
							CleanHistory(qs);
						}else if(qStr.contains("method=logout")){
						   handleLogout(qs);
						}else if(qStr.contains("method=login")){
						   handleLogin(qs);
						}else if(qStr.contains("method=loginRequest")){//分配本地登陆用户
							QQWeiBo weibo=WeiboUtils.allocWeiboUser();
							resTick[0]="loginRequest";
							if(weibo==null){
								resTick[1]="";
								resTick[2]="";
							}else{
								resTick[1]=weibo.getUser();
								resTick[2]=weibo.getPass();
							}
						}else if(qStr.contains("method=trueMsg")){//返回真相消息
							resTick[0]="trueMsg";
							resTick[1]=WeiboUtils.getTruthMsg();
						}else if(qStr.contains("msg")){
							handleMsg(qs);
						}
						// 返回JSon字符串
						Gson gson=new Gson();
						String json=gson.toJson(resTick);
						he.sendResponseHeaders(200,json.getBytes("utf-8").length);
						OutputStream os = he.getResponseBody();
						os.write(json.getBytes());
						os.close();
					} catch (Exception e) {
						logger.info("handle Exception");
					}

				}

				private void handleClickAction(QueryString qs) {
					try {
						Robot robot = new Robot();
						String action = qs.getParameter("action");
						logger.info("handleClickAction： "+qs.toString());
						int x=Integer.parseInt(qs.getParameter("xPos"));
						int y=Integer.parseInt(qs.getParameter("yPos"));
						if(action.equals("clickPosWithMsg")){ //点击特定位置，并且传送真相消息
							mouseMoveAndClick(robot, x, y);
					 		robot.delay(63);
					 		//首先删除全部的值
							robot.keyPress(KeyEvent.VK_CONTROL);
						    robot.delay(57);
							robot.keyPress(KeyEvent.VK_A);
						    robot.delay(111);
							robot.keyRelease(KeyEvent.VK_A);
						    robot.delay(45);
							robot.keyRelease(KeyEvent.VK_CONTROL);
						    robot.delay(135);
							robot.keyPress(KeyEvent.VK_DELETE);
						    robot.delay(111);
							robot.keyRelease(KeyEvent.VK_DELETE);
							String msg=qs.getParameter("msg");
							logger.info("clickPosWithMsg："+x+"*****"+y+"*****"+msg);
						    robot.delay(57);
							//消息粘贴到剪贴板
							StringSelection stsel = new StringSelection(msg);
					        Toolkit.getDefaultToolkit().getSystemClipboard().setContents(stsel, stsel);

					 		robot.delay(63);
							robot.keyPress(KeyEvent.VK_CONTROL);
						    robot.delay(57);
							robot.keyPress(KeyEvent.VK_V);
						    robot.delay(111);
							robot.keyRelease(KeyEvent.VK_V);
						    robot.delay(45);
							robot.keyRelease(KeyEvent.VK_CONTROL);
						    robot.delay(57);
							//mouseMoveAndClick(robot, x, y);
							
						}else if(action.equals("submitPosWithMsg")){ //点击特定位置，并且传送真相消息
							mouseMoveAndClick(robot, x, y);
					 		robot.delay(163);
					 		//首先删除全部的值
							robot.keyPress(KeyEvent.VK_CONTROL);
						    robot.delay(57);
							robot.keyPress(KeyEvent.VK_A);
						    robot.delay(111);
							robot.keyRelease(KeyEvent.VK_A);
						    robot.delay(45);
							robot.keyRelease(KeyEvent.VK_CONTROL);
						    robot.delay(1357);
							robot.keyPress(KeyEvent.VK_DELETE);
						    robot.delay(111);
							robot.keyRelease(KeyEvent.VK_DELETE);
							String msg=qs.getParameter("msg");
							logger.info("clickPosWithMsg："+x+"*****"+y+"*****"+msg);
						    robot.delay(257);
							//消息粘贴到剪贴板
							StringSelection stsel = new StringSelection(msg);
					        Toolkit.getDefaultToolkit().getSystemClipboard().setContents(stsel, stsel);

					 		robot.delay(163);
							robot.keyPress(KeyEvent.VK_CONTROL);
						    robot.delay(57);
							robot.keyPress(KeyEvent.VK_V);
						    robot.delay(111);
							robot.keyRelease(KeyEvent.VK_V);
						    robot.delay(45);
							robot.keyRelease(KeyEvent.VK_CONTROL);
						    robot.delay(257);
					 		robot.delay(1163);
							robot.keyPress(KeyEvent.VK_CONTROL);
						    robot.delay(57);
							robot.keyPress(KeyEvent.VK_ENTER);
						    robot.delay(111);
							robot.keyRelease(KeyEvent.VK_ENTER);
						    robot.delay(45);
							robot.keyRelease(KeyEvent.VK_CONTROL);
						    robot.delay(257);
							//mouseMoveAndClick(robot, x, y);
							
						}else if(action.equals("clickPosImg")){
							String imgPath="c:/java/images";
							FilenameFilter filter = new FilenameFilter() { 
							    public boolean accept(File dir, String name) { 
							        return name.startsWith("ja"); 
							    } 
							}; 
							//首先删除上次的随机文件
							logger.info("uploadedFile:="+uploadedFile);
							if(uploadedFile!=null){
								File rndFile=new File(uploadedFile);
								if(rndFile.isFile() && rndFile.exists()){     
									rndFile.delete();  
								}
							}
							
							File folder = new File(imgPath); 
							File[] listOfFiles = folder.listFiles(filter); 
							//计算有多少个可以使用的images文件，随机选择一个序号
							int seq=(int) (System.currentTimeMillis() %  listOfFiles.length);
							mouseMoveAndClick(robot, x, y);
							robot.delay(450);
							//把image文件路径复制到ClipBoard中！
							String file="c:\\java\\images\\ja"+seq+".jpg";
							if(seq<=9 && seq>0){
								file="c:\\java\\images\\ja0"+seq+".jpg";
							}else if(seq==0){
								file="c:\\java\\images\\ja01.jpg";
							}
							
							uploadedFile="c:\\java\\images\\v"+getRandomString(5)+".jpg";//随机生成上传文件名称
							//重新命名文件，并且执行文件缩放
							CopyFileForChannel(new File(file),new File(uploadedFile));
							imageZoom(new File(uploadedFile),uploadedFile);
							
							StringSelection stsel = new StringSelection(uploadedFile);
					        Toolkit.getDefaultToolkit().getSystemClipboard().setContents(stsel, stsel);
					        
					 		robot.delay(163);
							robot.keyPress(KeyEvent.VK_CONTROL);
						    robot.delay(57);
							robot.keyPress(KeyEvent.VK_V);
						    robot.delay(111);
							robot.keyRelease(KeyEvent.VK_V);
						    robot.delay(45);
							robot.keyRelease(KeyEvent.VK_CONTROL);
						    robot.delay(1357);
							//mouseMoveAndClick(robot, x, y);
						    logger.info("Press回车键：上传文件！");
						    robot.delay(1357);
							robot.keyPress(KeyEvent.VK_ENTER);
					 		robot.delay(113);
							robot.keyRelease(KeyEvent.VK_ENTER);
					 		robot.delay(1113);
							mouseMoveAndClick(robot, 506,381);//防止只按回车键无法上传图片文件！
					 		robot.delay(813);
						}else if(action.equals("clickPos")){
							logger.info("clickPos："+x+"*****"+y);
						    robot.delay(357);
							mouseMoveAndClick(robot, x, y);
						}else if(action.equals("msgPos")){
					 		robot.delay(163);
					 		//首先删除全部的值
							robot.keyPress(KeyEvent.VK_CONTROL);
						    robot.delay(157);
							robot.keyPress(KeyEvent.VK_A);
						    robot.delay(211);
							robot.keyRelease(KeyEvent.VK_A);
						    robot.delay(145);
							robot.keyRelease(KeyEvent.VK_CONTROL);
						    robot.delay(1357);
							robot.keyPress(KeyEvent.VK_DELETE);
						    robot.delay(111);
							robot.keyRelease(KeyEvent.VK_DELETE);
							String msg=qs.getParameter("msg");
							logger.info("clickPosWithMsg："+x+"*****"+y+"*****"+msg);
						    robot.delay(257);
							//消息粘贴到剪贴板
							StringSelection stsel = new StringSelection(msg);
					        Toolkit.getDefaultToolkit().getSystemClipboard().setContents(stsel, stsel);

					 		robot.delay(163);
							robot.keyPress(KeyEvent.VK_CONTROL);
						    robot.delay(57);
							robot.keyPress(KeyEvent.VK_V);
						    robot.delay(111);
							robot.keyRelease(KeyEvent.VK_V);
						    robot.delay(45);
							robot.keyRelease(KeyEvent.VK_CONTROL);
						}
					} catch (AWTException e) {
						logger.info("handleClickAction Exception");
						//e.printStackTrace();
					} catch (Exception e) {
						logger.info("handleClickAction Exception");
						//e.printStackTrace();
					}
					
				}
				//生成随机字符串
				private  String getRandomString(int length) { //length表示生成字符串的长度
				    String base = "abcdefghijklmnopqrstuvwxyz0123456789";   
				    Random random = new Random();   
				    StringBuffer sb = new StringBuffer();   
				    for (int i = 0; i < length; i++) {   
				        int number = random.nextInt(base.length());   
				        sb.append(base.charAt(number));   
				    }   
				    return sb.toString();   
				 }  
				private void handleMsg(QueryString qs) {
					String msg = qs.getParameter("msg");
					int seq=msgNum.incrementAndGet();
					ClipboardUtils clip = new ClipboardUtils();
					//logger.info("模拟键盘输入行为，发送真相短消息......"+ msg);
					clip.clickFireFox(msg);
				}
				
				private void handleLogout(QueryString qs) {
					try {
						Robot robot=new Robot();
						mouseMoveAndClick(robot, 1126,15);//把焦点转移到Firefox上！
						robot.delay(1129);
						//CTRL+SHIFT+DEL clean FF的缓存
						robot.keyPress(KeyEvent.VK_CONTROL);
						robot.delay(57);
						robot.keyPress(KeyEvent.VK_SHIFT);
						robot.delay(111);
						robot.keyPress(KeyEvent.VK_DELETE);
						robot.delay(45);
						robot.keyRelease(KeyEvent.VK_DELETE);
						robot.delay(57);
						robot.keyRelease(KeyEvent.VK_SHIFT);
						robot.delay(111);
						robot.keyRelease(KeyEvent.VK_CONTROL);
						robot.delay(3211);
						robot.keyPress(KeyEvent.VK_ENTER);
						robot.delay(345);
						robot.keyRelease(KeyEvent.VK_ENTER);
						logger.info("clickFireFoxLogout: FF history cleaned!");
						robot.delay(5111);
						robot.keyRelease(KeyEvent.VK_ALT);
						robot.delay(228);
						robot.keyPress(KeyEvent.VK_F4);
						robot.delay(111);
						robot.keyRelease(KeyEvent.VK_F4);
						robot.delay(145);
						robot.keyRelease(KeyEvent.VK_ALT);
						robot.delay(157);
						logger.info("clickFireFoxLogout: FF Closed!");
					} catch (AWTException e) {
						logger.error(e);
					}
					//ALT+F4 关闭FF
					logger.info("clickFireFoxLogoutADSL: FF closed !");
				}
				//logout时挂断ADSL, 私信发送模块处理
				private void CleanHistory(QueryString qs) {
					try {
						Robot robot = new Robot();
						robot.delay(1129);
						mouseMoveAndClick(robot, 1126,15);//把焦点转移到Firefox上！
						robot.delay(1129);
				 		//CTRL+SHIFT+DEL clean FF的缓存
						robot.keyPress(KeyEvent.VK_CONTROL);
					    robot.delay(257);
						robot.keyPress(KeyEvent.VK_SHIFT);
					    robot.delay(211);
						robot.keyPress(KeyEvent.VK_DELETE);
					    robot.delay(170);
						robot.keyRelease(KeyEvent.VK_DELETE);
					    robot.delay(90);
						robot.keyRelease(KeyEvent.VK_SHIFT);
					    robot.delay(60);
						robot.keyRelease(KeyEvent.VK_CONTROL);
					    robot.delay(2111);
						robot.keyPress(KeyEvent.VK_ENTER);
					    robot.delay(95);
						robot.keyRelease(KeyEvent.VK_ENTER);
						logger.info("clickFireFoxLogout: FF history cleaned!");
					}catch (Exception e) {
						logger.error("Exception in clickFireFoxLogout!");
					}finally{
					}
				}
				//logout时挂断ADSL, 私信发送模块处理
				private void handleLogoutADSL(QueryString qs) {
					try {
						Robot robot = new Robot();
						robot.delay(1129);
						mouseMoveAndClick(robot, 1126,15);//把焦点转移到Firefox上！
						robot.delay(1129);
				 		//CTRL+SHIFT+DEL clean FF的缓存
						robot.keyPress(KeyEvent.VK_CONTROL);
					    robot.delay(457);
						robot.keyPress(KeyEvent.VK_SHIFT);
					    robot.delay(311);
						robot.keyPress(KeyEvent.VK_DELETE);
					    robot.delay(445);
						robot.keyRelease(KeyEvent.VK_DELETE);
					    robot.delay(311);
						robot.keyRelease(KeyEvent.VK_SHIFT);
					    robot.delay(457);
						robot.keyRelease(KeyEvent.VK_CONTROL);
					    robot.delay(2111);
						robot.keyPress(KeyEvent.VK_ENTER);
					    robot.delay(545);
						robot.keyRelease(KeyEvent.VK_ENTER);
						logger.info("clickFireFoxLogout: FF history cleaned!");
					    robot.delay(5111);
						//执行ADSL脚本hangup脚本
						Runtime.getRuntime().exec(ConstantStri.hangupADSL);
						logger.info("clickFireFoxLogoutADSL:  ADSL hangup and FF restart!");
					}catch (Exception e) {
						logger.info("Exception in clickFireFoxLogout!");
					}finally{
					}
				}
				private void handleLogin(QueryString qs) {
					ClipboardUtils clip = new ClipboardUtils();
					String user=qs.getParameter("user");
					String pass=qs.getParameter("pass");
					String verify=qs.getParameter("verify");
					logger.info("模拟键盘输入行为，handleLogin...");
					clip.clickFireFoxLogin(user,pass,verify);
				}
				protected  void type(Robot robot,String s)
				  {
				    byte[] bytes;
					try {
						bytes = s.getBytes("UTF-8");
					    for (byte b : bytes){
					        int code = b;
					        //System.out.print(" Key Code="+code+";");
					        // keycode only handles [A-Z] (which is ASCII decimal [65-90])
					        if (code > 96 && code < 123){
					    	  code = code - 32;
					        }
						    robot.delay(5);
						    robot.keyPress(code);
						    robot.delay(4);
						    robot.keyRelease(code);
					    }//FOR
					} catch (UnsupportedEncodingException e) {
						e.printStackTrace();
					}
				  }

				/* 鼠标移动，并且20毫秒以后点击对应的坐标 */
				protected void mouseMoveAndClick(Robot robot,int x, int y) {
					robot.mouseMove(x, y);
					robot.delay(345);
					robot.mousePress(KeyEvent.BUTTON1_MASK);
					robot.delay(222);
					robot.mouseRelease(KeyEvent.BUTTON1_MASK);// 松开鼠标左键
				}
				private void mouseMoveAndDoubleClick(Robot robot,int x, int y) {
					robot.mouseMove(x, y);
					robot.delay(845);
					robot.mousePress(KeyEvent.BUTTON1_MASK);
					robot.delay(90);
					robot.mouseRelease(KeyEvent.BUTTON1_MASK);// 松开鼠标左键
					robot.delay(110);
					robot.mousePress(KeyEvent.BUTTON1_MASK);
					robot.delay(119);
					robot.mouseRelease(KeyEvent.BUTTON1_MASK);// 松开鼠标左键
				}
				public void imageZoom(File in,String outFile) {

					try {
						BufferedImage src = ImageIO.read(in); // 读入文件
						int width = src.getWidth(); // 得到源图宽
						int height = src.getHeight(); // 得到源图长
						int xScale=(int) Math.ceil(((System.currentTimeMillis() %  30)/1000+1)*width);
						int yScale=(int) Math.ceil(((System.currentTimeMillis() %  30)/1000+1)*height);
			                          
			            //  获取一个宽、长是xScale 和 yScale的图像实例
						Image image = src.getScaledInstance(xScale, yScale, Image.SCALE_DEFAULT);
						BufferedImage tag = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);  //缩放图像
						Graphics g = tag.getGraphics();
						g.drawImage(image, 0, 0, null); // 绘制缩小后的图
						g.dispose();
						ByteArrayOutputStream bos = new ByteArrayOutputStream();
						ImageIO.write(tag,"JPEG",bos);// 输出到bos
						 
						FileOutputStream out = new FileOutputStream(outFile);
						out.write(bos.toByteArray());  //写文件
						out.close();
					} catch (IOException e) {
						e.printStackTrace();
				    }
				}
				//复制拷贝文件
			    public long CopyFileForChannel(File f1,File f2) throws Exception{
			        long time=new Date().getTime();
			        int length=2097152;
			        FileInputStream in=new FileInputStream(f1);
			        FileOutputStream out=new FileOutputStream(f2);
			        FileChannel inC=in.getChannel();
			        FileChannel outC=out.getChannel();
			        ByteBuffer b=null;
			        while(true){
			            if(inC.position()==inC.size()){
			                inC.close();
			                outC.close();
			                return new Date().getTime()-time;
			            }
			            if((inC.size()-inC.position())<length){
			                length=(int)(inC.size()-inC.position());
			            }else
			                length=2097152;
			            b=ByteBuffer.allocateDirect(length);
			            inC.read(b);
			            b.flip();
			            outC.write(b);
			            outC.force(false);
			        }
			    }			

			});
			server.start();
			logger.info("Monitoring " + port + " port");
		} catch (Exception e) {
			logger.info("localHttpLisener Exception");
			boolean jv;
			try {
				jv = ControlUtils.isProcessRunging("java.exe");
				if(jv){
					logger.info("JDK running，Killing it");
					ControlUtils.killJAVA();	
				}
			} catch (Exception e1) {
				logger.info("JDK running，Killing it");
				//e1.printStackTrace();
			}
			logger.info("Http local server start Exception!");
			e.printStackTrace();
		}

	}

	public static void main(String[] args) throws Exception {
		//truthArrayInit();
		//ControlUtils.killFirefox();
		AutoClickLocalServer lsn=new AutoClickLocalServer(9988);
		lsn.start();
	}


}
